#ifndef JSON_DATA_H
#define JSON_DATA_H

#include <iostream>
#include <string>
typedef std::wstring SimWString;
typedef std::wstring::iterator SimWStringIter;

namespace simframework
{
	namespace json
	{
		enum {
			JSON_FAIL = 0,
			JSON_SUCCESS,
			JSON_NULL
		};
		enum JSON_Type {
			JSON_OBJECT = 0,
			JSON_ARRAY,
			JSON_STRING,
			JSON_INTEGER,
			JSON_FLOAT,
			JSON_BOOLEAN
		};

		class JSON_Array;

		struct JSON_Abstract {};

		class JSON_Object : public JSON_Abstract {
			SimWString		m_valueStr;
			SimWStringIter	m_startIt;
			SimWStringIter	m_endIt;
			JSON_Abstract *	getValue(JSON_Type type, SimWString name, int* error);
		public:
			JSON_Object(SimWString str);
			JSON_Object *	getObjectValueByKey(SimWString name, int* error = NULL);
			JSON_Array *	getArrayValueByKey(SimWString name, int* error = NULL);
			SimWString		getStringValueByKey(SimWString name, int* error = NULL);
			double			getFloatValueByKey(SimWString name, int* error = NULL);
			int				getIntValueByKey(SimWString name, int* error = NULL);
			bool			getBooleanValueByKey(SimWString name, int* error = NULL);
		};

		class JSON_Array : public JSON_Abstract {
			SimWString		m_valueStr;
			SimWStringIter	m_startIt;
			SimWStringIter	m_endIt;
			unsigned int	m_valueCount;
			JSON_Abstract *	getValue(JSON_Type type, unsigned int id, int* error);
		public:
			JSON_Array(SimWString str);
			JSON_Object *	getObjectValueForId(unsigned int id, int* error = NULL);
			JSON_Array *	getArrayValueForId(unsigned int id, int* error = NULL);
			SimWString		getStringValueForId(unsigned int id, int* error = NULL);
			double			getFloatValueForId(unsigned int id, int* error = NULL);
			int				getIntValueForId(unsigned int id, int* error = NULL);
			bool			getBooleanValueForId(unsigned int id, int* error = NULL);
		};

		struct JSON_String : public JSON_Abstract	{ SimWString strValue; };
		struct JSON_Float : public JSON_Abstract	{ double fValue; };
		struct JSON_Integer : public JSON_Abstract	{ int iValue; };
		struct JSON_Boolean : public JSON_Abstract	{ bool bValue; };

		static /*const*/ JSON_Object	DEFAULT_JSON_OBJECT(L"");
		static /*const*/ JSON_Array		DEFAULT_JSON_ARRAY(L"");
		static /*const*/ JSON_String	DEFAULT_JSON_STRING;
		static /*const*/ JSON_Boolean	DEFAULT_JSON_BOOLEAN;
		static /*const*/ JSON_Float		DEFAULT_JSON_FLOAT;
		static /*const*/ JSON_Integer	DEFAULT_JSON_INTEGER;
		static /*const*/ JSON_Abstract	DEFAULT_JSON_ABSTRACT;
	}
}

#endif